package fileutil

import (
	"bufio"
	"errors"
	"fmt"
	"github.com/sirupsen/logrus"
	"io"
	"os"
	"path/filepath"
	"playbook/ginsvr/src/global"
	"playbook/ginsvr/src/orm"
	"strings"
)

func GetClearFile(path string, name string) *os.File {
	localpath := orm.GetLocalPath(global.USER)

	path = SepTransform(path)

	filepath := localpath.LocalPath + global.PTHSEP + path

	if FileExist(filepath, true) {
		os.Remove(filepath)
	}
	err := os.MkdirAll(filepath, 0777)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":      err,
			"filepath": filepath,
		}).Error("dir creat err.")
		return nil
	}

	filename := filepath + global.PTHSEP + name
	file, err := os.Create(filename)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":      err,
			"filepath": filepath,
		}).Error("file creat err.")
		return nil
	}

	return file
}

func Filewrite(path string, content []string) {
	localpath := orm.GetLocalPath(global.USER)

	path = SepTransform(path)

	filepath := localpath.LocalPath + global.PTHSEP + path

	if FileExist(filepath, true) {
		os.Remove(filepath)
	}
	file, err := os.Create(filepath)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":      err,
			"filepath": filepath,
		}).Error("file open err.")
		return
	}

	defer file.Close()

	for _, line := range content {
		_, err = io.WriteString(file, line)
		if err != nil {
			global.LOG.WithFields(logrus.Fields{
				"err":      err,
				"filepath": filepath,
			}).Error("file write err.")
			return
		}
	}
}

func FileExist(path string, isabs bool) bool {
	if !isabs {
		localpath := orm.GetLocalPath(global.USER)
		path = localpath.LocalPath + global.PTHSEP + path
	}

	path = SepTransform(path)

	_, err := os.Stat(path)

	if err != nil {
		if os.IsExist(err) {
			return true
		}
		return false
	}

	return true
}

func ReadSrcFile(srcpath string, isabs bool) []string {

	var fLst []string

	var path = srcpath
	path = SepTransform(path)

	if !isabs {
		localpath := orm.GetLocalPath(global.USER)
		path = localpath.LocalPath + global.PTHSEP + srcpath
	}
	file, err := os.Open(path)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":          err,
			"javafilepath": path,
		}).Error("open java source file err.")
	}

	defer file.Close()
	global.LOG.Debug(file.Name())
	reader := bufio.NewReader(file)

	for {
		str, err := reader.ReadString('\n') //按行读取，值赋予给str
		if err == io.EOF {
			break
		}
		if err != nil {
			global.LOG.WithFields(logrus.Fields{
				"err": err,
			}).Error("java source file read err.")
			break
		}

		fLst = append(fLst, str)
	}

	return fLst
}

func DeleteFile(srcpath string, isabs bool) error {

	var path = srcpath

	path = SepTransform(path)

	if !isabs {
		localpath := orm.GetLocalPath(global.USER)
		path = localpath.LocalPath + global.PTHSEP + srcpath
	}

	if isDir(path) {
		err := os.RemoveAll(path)
		return err
	} else if FileExist(path, true) {
		err := os.Remove(path)
		return err
	}
	return nil
}

// 判断所给路径是否为文件夹
func isDir(path string) bool {
	s, err := os.Stat(path)
	if err != nil {
		return false
	}
	return s.IsDir()
}

func GetRelaPath(path string) string {
	localpath := orm.GetLocalPath(global.USER)
	pathcut := localpath.LocalPath + global.PTHSEP

	srcpath := strings.Replace(path, pathcut, "", -1)

	return srcpath
}

func GetAbsPath(srcpath string) string {
	localpath := orm.GetLocalPath(global.USER)

	abspath := localpath.LocalPath + global.PTHSEP + srcpath

	return abspath
}

func SepTransform(path string) string {
	if global.OSTYPE == "windows" {
		path = strings.ReplaceAll(path, "/", global.PTHSEP)
	} else if global.OSTYPE == "linux" {
		path = strings.ReplaceAll(path, "\\", global.PTHSEP)
	}

	return path
}

func SepTransLux(path string) string {
	path = strings.ReplaceAll(path, "\\", "/")
	return path
}

func DeleteProjectFile(srcpathList []string) error {
	for _, srcpath := range srcpathList {
		files, err := filepath.Glob(filepath.Join(srcpath, "*"))
		if err != nil {
			return err
		}
		for _, file := range files {
			fmt.Println("删除文件" + file)
			err = os.RemoveAll(file)
			if err != nil {
				return err
			}
		}
	}
	return nil
}

func CopyDir(sourcePath string, targetPath string) error {
	// 检测目录正确性
	if srcInfo, err := os.Stat(sourcePath); err != nil {
		fmt.Println(err.Error())
		return err
	} else {
		if !srcInfo.IsDir() {
			e := errors.New("srcPath不是一个正确的目录！")
			fmt.Println(e.Error())
			return e
		}
	}

	// 判断新输入路径是否合法
	_, errPath := pathExists(targetPath)
	if errPath != nil {
		return errPath
	}

	err := filepath.Walk(sourcePath, func(path string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}
		path = SepTransform(path)
		projectPath := SepTransform(sourcePath)
		destPath := SepTransform(targetPath)
		destNewPath := strings.Replace(path, projectPath, destPath, -1)
		if path == destNewPath {
			return nil
		}
		if !f.IsDir() {
			fmt.Println("复制文件:" + path + " 到 " + destNewPath)
			copyFile(path, destNewPath, true)
		} else if f.IsDir() {
			fmt.Println("复制文件夹:" + path + " 到 " + destNewPath)
			copyFile(path, destNewPath, false)
		}
		return nil
	})
	if err != nil {
		fmt.Printf(err.Error())
	}
	return err
}

// 生成目录并拷贝文件
func copyFile(src, dest string, flag bool) (w int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		fmt.Println(err.Error())
		return
	}
	defer srcFile.Close()
	//分割path目录
	destSplitPathDirs := strings.Split(dest, global.PTHSEP)
	//检测时候存在目录
	destSplitPath := ""
	for index, dir := range destSplitPathDirs {
		if index < len(destSplitPathDirs)-1 {
			destSplitPath = destSplitPath + dir + global.PTHSEP
			b, _ := pathExists(destSplitPath)
			if b == false {
				fmt.Println("创建目录:" + destSplitPath)
				//创建目录
				err := os.Mkdir(destSplitPath, os.ModePerm)
				if err != nil {
					fmt.Println(err)
				}
			}
		}
	}
	if flag {
		dstFile, err := os.Create(dest)
		if err != nil {
			fmt.Println(err.Error())
			return w, err
		}
		defer dstFile.Close()
		return io.Copy(dstFile, srcFile)
	} else {
		err = os.MkdirAll(dest, os.ModePerm)
		if err != nil {
			global.LOG.WithFields(logrus.Fields{
				"err":      err,
				"filepath": dest,
			}).Error("dir creat err.")
			return w, err
		}
	}
	return
}

// 检测文件夹路径是否存在
func pathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

// 复制文件
func CopyFile(newpath string, oldpath string) {

	newpath = SepTransform(newpath)
	localpath := orm.GetLocalPath(global.USER)

	var filenew *os.File
	var err error
	if !FileExist(newpath, false) {
		temp := strings.Split(newpath, global.PTHSEP)
		path := temp[0]

		for i := 1; i < len(temp)-1; i++ {
			path = path + global.PTHSEP + temp[i]
		}
		name := temp[len(temp)-1]
		filenew = GetClearFile(path, name)
	} else {
		newpath = localpath.LocalPath + global.PTHSEP + newpath
		filenew, err = os.OpenFile(newpath, os.O_RDWR, 0666)
		if err != nil {
			global.LOG.WithFields(logrus.Fields{
				"err":          err,
				"javafilepath": newpath,
			}).Error("open java source file err.")
		}
	}

	defer filenew.Close()

	oldpath = SepTransform(oldpath)
	oldpath = localpath.LocalPath + global.PTHSEP + oldpath
	fileold, err := os.Open(oldpath)
	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err":          err,
			"javafilepath": newpath,
		}).Error("open java source file err.")
	}

	defer fileold.Close()
	_, err = io.Copy(filenew, fileold)

	if err != nil {
		global.LOG.WithFields(logrus.Fields{
			"err": err,
		}).Error("copy file err.")
	}

}

// 创建文件夹
func MakeDir(path string, srcPathList []string) error {
	localpath := orm.GetLocalPath(global.USER)
	for _, srcPath := range srcPathList {
		path = SepTransform(path)
		filepath := localpath.LocalPath + global.PTHSEP + path + global.PTHSEP + srcPath
		// 判断路径是否合法
		_, err := pathExists(filepath)
		if err != nil {
			return err
		}
		if !FileExist(filepath, true) {
			err := os.MkdirAll(filepath, os.ModePerm)
			if err != nil {
				global.LOG.WithFields(logrus.Fields{
					"err":      err,
					"filepath": filepath,
				}).Error("dir creat err.")
				return err
			}
		}
	}
	return nil
}
